package com.ruoyi.web.jobs;

import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.ruoyi.a2.domain.A2DynamicsInfo;
import com.ruoyi.a2.domain.A2Pdcc;
import com.ruoyi.a2.domain.AdsDynamicsInfo;
import com.ruoyi.a2.domain.AisDynamicsInfo;
import com.ruoyi.a2.service.IA2DynamicsInfoService;
import com.ruoyi.a2.service.IA2PdccService;
import com.ruoyi.a2.service.IAdsDynamicsInfoService;
import com.ruoyi.a2.service.IAisDynamicsInfoService;
import com.ruoyi.a2.service.ITool2aBlankValueFillService;
import com.ruoyi.a2.service.ITool2aEOfAbnormalValueService;
import com.ruoyi.a2.service.ITool2aSpaceTimeResampleService;
import com.ruoyi.common.constant.CharConstant;
import com.ruoyi.common.constant.FileConstant;
import com.ruoyi.common.enums.ActivityTypeEnum;
import com.ruoyi.common.enums.CleanStatusEnum;
import com.ruoyi.common.enums.CommonOKNOEnum;
import com.ruoyi.common.enums.FlightPathTypeEnum;
import com.ruoyi.common.utils.Date2Utils;
import com.ruoyi.common.utils.IdentitiesUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.TxtUtils;
import com.ruoyi.constant.WebSocketConstant;
import com.ruoyi.ky450.service.WebSocketServer;
import com.ruoyi.ky450.vo.WebSocketVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时引接2a数据.
 *
 * @author :yanlixiong
 * @date :2025-02-14 14:42:20
 */
@Configuration
@Slf4j
public class ConnectA2DataJob {

    @Value("${a2.csvPath.aisInput:def}")
    private String csvPathAisInput;

    @Value("${a2.csvPath.aisBak:def}")
    private String csvPathAisBak;

    @Value("${a2.csvPath.adsInput:def}")
    private String csvPathAdsInput;

    @Value("${a2.csvPath.adsBak:def}")
    private String csvPathAdsBak;

    @Autowired
    private IA2DynamicsInfoService a2DynamicsInfoService;

    @Autowired
    private IAisDynamicsInfoService aisDynamicsInfoService;

    @Autowired
    private IAdsDynamicsInfoService adsDynamicsInfoService;

    @Autowired
    private IA2PdccService a2PdccService;

    @Autowired
    private WebSocketServer webSocketServer;

    //异常值剔除
    @Autowired
    private ITool2aEOfAbnormalValueService tool2aEOfAbnormalValueService;

    //空值填充
    @Autowired
    private ITool2aBlankValueFillService tool2aBlankValueFillService;

    //时空重采样
    @Autowired
    private ITool2aSpaceTimeResampleService tool2aSpaceTimeResampleService;


    /**
     * 读取指定目录下的csv文件(AIS)
     * <p>
     * 上一次任务结束后等待指定时间执行下次任务；
     * 例如：每隔3秒执行定时任务，0秒开始第一次执行，任务执行花费5秒，则第二次任务执行开始时间是第 0+5+3=8 秒.
     *
     * @author :yanlixiong
     * @date :2025-02-14 14:43:33
     */
    @Scheduled(fixedDelayString = "${a2.jobs.connectA2DataJob}")
    public void aisCsv() {
        try {
            List<File> fileList = FileUtils.getFileByDir(csvPathAisInput, FileConstant.FILE_SUFFIX_CSV);
            if(!CollectionUtils.isEmpty(fileList)){
                for(File file:fileList){
                    String absoluteFile = file.getAbsolutePath();
                    String name = file.getName();
                    List<String> dataList = TxtUtils.read(absoluteFile);

                    if(!CollectionUtils.isEmpty(dataList)){
                        List<AisDynamicsInfo> aisDynamicsInfoList = Lists.newArrayList();
                        int size = dataList.size();
                        for (int i = 1; i <size ; i++) {
                            String data = dataList.get(i);
                            String[] dataArr = data.split(CharConstant.SPLIT_DH);
                            //mmsi,基准时间,经度,纬度,航速,航向------舰船
                            AisDynamicsInfo aisDynamicsInfo = new AisDynamicsInfo();
                            aisDynamicsInfo.setMmsi(dataArr[0]);
                            if(i==1) {
                                aisDynamicsInfo.setStatus(ActivityTypeEnum.DATA_2.getCode());
                            }else if(i==size-1){
                                aisDynamicsInfo.setStatus(ActivityTypeEnum.DATA_1.getCode());
                            }
                            aisDynamicsInfo.setBaseTime(Date2Utils.strToDateTime(dataArr[1]));
                            //当经纬度不为空的时候，再进行以下操作
                            if(StringUtils.isNotBlank(dataArr[2]) && StringUtils.isNotBlank(dataArr[3])) {
                                Double Lon = Double.valueOf(dataArr[2]);
                                Double Lat = Double.valueOf(dataArr[3]);
                                aisDynamicsInfo.setLon(Lon);
                                aisDynamicsInfo.setLat(Lat);
                                String geom = "ST_SetSRID(ST_MakePoint(" + Lon + ", " + Lat + "), 4326)";
                                aisDynamicsInfo.setGeom(geom);
                            }
                            if(StringUtils.isNotBlank(dataArr[4])){
                                aisDynamicsInfo.setSpeed(Double.valueOf(dataArr[4]));
                            }
                            if(StringUtils.isNotBlank(dataArr[5])) {
                                aisDynamicsInfo.setWay(Double.valueOf(dataArr[5]));
                            }

                            aisDynamicsInfoList.add(aisDynamicsInfo);
                        }


                        //清洗逻辑处理
                        //1、查询点位数据清洗配置
                        List<A2Pdcc> a2PdccList = a2PdccService.getListByEnableOK();
                        if(!CollectionUtils.isEmpty(a2PdccList)) {
                            List<A2Pdcc> a2PdccList1 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_1.getCode().equals(v.getType())).collect(Collectors.toList());
                            List<A2Pdcc> a2PdccList2 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_2.getCode().equals(v.getType())).collect(Collectors.toList());
                            List<A2Pdcc> a2PdccList3 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_3.getCode().equals(v.getType())).collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(a2PdccList1)) {
                                log.info("异常值剔除......");
                                //a2DynamicsInfoList = tool2aEOfAbnormalValueService.handle(a2DynamicsInfoList, a2PdccList1.get(0).getThreshold());
                            }

                            if (!CollectionUtils.isEmpty(a2PdccList2)) {
                                log.info("空值填充......");
                                //a2DynamicsInfoList = tool2aBlankValueFillService.handle(a2DynamicsInfoList, a2PdccList2.get(0).getIntervalTime());
                            }

                            if (!CollectionUtils.isEmpty(a2PdccList3)) {
                                log.info("时空重采样......");
                                //a2DynamicsInfoList = tool2aSpaceTimeResampleService.handle(a2DynamicsInfoList);
                            }
                        }

                        for(AisDynamicsInfo aisDynamicsInfo:aisDynamicsInfoList){
                            aisDynamicsInfoService.insertAisDynamicsInfo(aisDynamicsInfo);

                            //利用webSocket推送实时轨迹
                            /*WebSocketVo vo = new WebSocketVo(WebSocketConstant.REAL_TIME_TRAJECTORY,a2DynamicsInfo);
                            webSocketServer.sendInfo(JSON.toJSONString(vo));
                            Thread.sleep(5000);*/
                        }

                        //备份并删除文件
                        FileUtils.bakFile(absoluteFile,csvPathAisBak+name);
                    }
                }
            }
        } catch (Exception e) {
            log.error("读取指定目录下的csv文件(AIS).error|{}",e);
        }
    }

    /**
     * 读取指定目录下的csv文件(ADS-B)
     * <p>
     * 上一次任务结束后等待指定时间执行下次任务；
     * 例如：每隔3秒执行定时任务，0秒开始第一次执行，任务执行花费5秒，则第二次任务执行开始时间是第 0+5+3=8 秒.
     *
     * @author :yanlixiong
     * @date :2025-02-14 14:43:33
     */
    @Scheduled(fixedDelayString = "${a2.jobs.connectA2DataJob}")
    public void adsCsv() {
        try {
            List<File> fileList = FileUtils.getFileByDir(csvPathAdsInput, FileConstant.FILE_SUFFIX_CSV);
            if(!CollectionUtils.isEmpty(fileList)){
                for(File file:fileList){
                    String absoluteFile = file.getAbsolutePath();
                    String name = file.getName();
                    List<String> dataList = TxtUtils.read(absoluteFile);

                    if(!CollectionUtils.isEmpty(dataList)){
                        List<AdsDynamicsInfo> adsDynamicsInfoList = Lists.newArrayList();
                        int size = dataList.size();
                        for (int i = 1; i <size ; i++) {
                            String data = dataList.get(i);
                            String[] dataArr = data.split(CharConstant.SPLIT_DH);
                            //icao,基准时间,经度,纬度,航速,航向,高度------飞机
                            AdsDynamicsInfo adsDynamicsInfo = new AdsDynamicsInfo();
                            adsDynamicsInfo.setIcao(dataArr[0]);
                            if(i==1) {
                                adsDynamicsInfo.setStatus(ActivityTypeEnum.DATA_2.getCode());
                            }else if(i==size-1){
                                adsDynamicsInfo.setStatus(ActivityTypeEnum.DATA_1.getCode());
                            }
                            adsDynamicsInfo.setBaseTime(Date2Utils.strToDateTime(dataArr[1]));
                            //当经纬度不为空的时候，再进行以下操作
                            if(StringUtils.isNotBlank(dataArr[2]) && StringUtils.isNotBlank(dataArr[3])) {
                                Double Lon = Double.valueOf(dataArr[2]);
                                Double Lat = Double.valueOf(dataArr[3]);
                                adsDynamicsInfo.setLon(Lon);
                                adsDynamicsInfo.setLat(Lat);
                                String geom = "ST_SetSRID(ST_MakePoint(" + Lon + ", " + Lat + "), 4326)";
                                adsDynamicsInfo.setGeom(geom);
                            }
                            if(StringUtils.isNotBlank(dataArr[4])){
                                adsDynamicsInfo.setSpeed(Double.valueOf(dataArr[4]));
                            }
                            if(StringUtils.isNotBlank(dataArr[5])) {
                                adsDynamicsInfo.setWay(Double.valueOf(dataArr[5]));
                            }
                            if(StringUtils.isNotBlank(dataArr[6])) {
                                adsDynamicsInfo.setGeoHeight(Double.valueOf(dataArr[6]));
                            }

                            adsDynamicsInfoList.add(adsDynamicsInfo);
                        }


                        //清洗逻辑处理
                        //1、查询点位数据清洗配置
                        List<A2Pdcc> a2PdccList = a2PdccService.getListByEnableOK();
                        if(!CollectionUtils.isEmpty(a2PdccList)) {
                            List<A2Pdcc> a2PdccList1 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_1.getCode().equals(v.getType())).collect(Collectors.toList());
                            List<A2Pdcc> a2PdccList2 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_2.getCode().equals(v.getType())).collect(Collectors.toList());
                            List<A2Pdcc> a2PdccList3 = a2PdccList.stream().filter(v -> CleanStatusEnum.DATA_3.getCode().equals(v.getType())).collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(a2PdccList1)) {
                                log.info("异常值剔除......");
                                //a2DynamicsInfoList = tool2aEOfAbnormalValueService.handle(a2DynamicsInfoList, a2PdccList1.get(0).getThreshold());
                            }

                            if (!CollectionUtils.isEmpty(a2PdccList2)) {
                                log.info("空值填充......");
                                //a2DynamicsInfoList = tool2aBlankValueFillService.handle(a2DynamicsInfoList, a2PdccList2.get(0).getIntervalTime());
                            }

                            if (!CollectionUtils.isEmpty(a2PdccList3)) {
                                log.info("时空重采样......");
                                //a2DynamicsInfoList = tool2aSpaceTimeResampleService.handle(a2DynamicsInfoList);
                            }
                        }

                        for(AdsDynamicsInfo adsDynamicsInfo:adsDynamicsInfoList){
                            adsDynamicsInfoService.insertAdsDynamicsInfo(adsDynamicsInfo);

                            //利用webSocket推送实时轨迹
                            /*WebSocketVo vo = new WebSocketVo(WebSocketConstant.REAL_TIME_TRAJECTORY,a2DynamicsInfo);
                            webSocketServer.sendInfo(JSON.toJSONString(vo));
                            Thread.sleep(5000);*/
                        }

                        //备份并删除文件
                        FileUtils.bakFile(absoluteFile,csvPathAdsBak+name);
                    }
                }
            }
        } catch (Exception e) {
            log.error("读取指定目录下的csv文件(ADS-B).error|{}",e);
        }
    }


}
